package com.longway.app.common;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.ehcache.CacheKit;
import com.longway.common.constant.Const;
import com.longway.common.model.BaseDept;
import com.longway.common.model.BaseRole;
import com.longway.common.model.BaseSession;
import com.longway.common.model.BaseUser;
import com.longway.common.service.DbService;
import com.longway.core.toolbox.Func;
import java.util.Date;
import java.util.List;

/**
 * 登录业务
 */
public class AppCommonService{
	
	public static final AppCommonService me = new AppCommonService();

	private BaseUser baseuserDao = new BaseUser().dao();
	private BaseRole baseRoleDao = new BaseRole().dao();
	private BaseDept baseDeptDao = new BaseDept().dao();


	public BaseUser getAppLoginAccountWithSessionId(String sessionId) {
		return CacheKit.get(Const.apploginAccountCacheName, sessionId);
	}

	public BaseUser loginWithSessionId(String sessionId, String loginIp) {
		BaseSession session = BaseSession.dao.findById(sessionId);
		if (session == null) {      // session 不存在
			return null;
		}
		if (session.isExpired()) {  // session 已过期
			session.delete();		// 被动式删除过期数据，此外还需要定时线程来主动清除过期数据
			return null;
		}
		BaseUser loginAccount = baseuserDao.findById(session.getAccountId());
		// 找到 loginAccount 并且 是正常状态 才允许登录
		if (loginAccount != null && loginAccount.isStatusOk()) {
			loginAccount.removeSensitiveInfo();                                 // 移除 password 与 salt 属性值
			loginAccount.put("sessionId", sessionId);                          // 保存一份 sessionId 到 loginAccount 备用
			joinRoleName(loginAccount);
			joinDeptName(loginAccount);
			CacheKit.put(Const.apploginAccountCacheName, sessionId, loginAccount);

			String msg = Func.format("[sessionID]: {} [sessionHost]: {}", session.getId(),loginIp);
			createLoginLog("登录",loginAccount.getId(),"MobileLoginController","loginWithSessionId","1",msg, loginIp);
			return loginAccount;
		}
		return null;
	}
	
	public void joinRoleName(Model model) {
		joinRole("roleid", model, "rolename");
	}
	
	public void joinDeptName(Model model) {
		joinDept("deptid", model, "deptname");
	}


	public void join(String joinOnField, List<? extends Model> modelList, String... joinAttrs) {
		if (modelList != null) {
			for (Model m : modelList) {
				joinRole(joinOnField, m, joinAttrs);
			}
		}
	}

	/**
	 * 在 User 等模块，需要关联查询获取 Role 对象的 name时使用此方法
	 * 避免使用关联查询，优化性能，在使用中更关键的地方在于缓存的清除
	 * @param joinOnField join 使用的字段名
	 * @param model 需要 join 的 model
	 * @param joinAttrs 需要 join 到 model 中的的属性名称
	 */
	public void joinRole(String joinOnField, Model model, String... joinAttrs) {
		String roleIds = model.getStr(joinOnField);
		if(roleIds == null) {
			throw new RuntimeException("Model 中的 \"" + joinOnField  + "\" 属性值不能为 null");
		}
		String[] roleIdsArray = roleIds.split(",");
		for(String roleId : roleIdsArray){
			BaseRole baseRole = CacheKit.get(Const.ROLE_CACHE, "findById_"+roleId);
	        if (baseRole == null) {
	        	baseRole = baseRoleDao.findById(roleId);
	            if (baseRole != null) {
	                CacheKit.put(Const.ROLE_CACHE, "findById_"+roleId, baseRole);
	            }
	        }
	    	if (baseRole != null) {
				for (String attr : joinAttrs) {
					model.put(attr, model.get(attr)+" "+baseRole.get(attr));
				}
			}else {
				throw new RuntimeException("未找到 BaseRole ,BaseRole 的 id 值为：" + roleId + " 可能是数据库数据不一致");
			}
		}
    	
	}
	
	public void joinDept(String joinOnField, Model model, String... joinAttrs) {
		Long deptId = model.getLong(joinOnField);
		if (deptId == null) {
			throw new RuntimeException("Model 中的 \"" + joinOnField  + "\" 属性值不能为 null");
		}

		// 优先从缓存中取，未命中缓存则从数据库取
		BaseDept baseDept = CacheKit.get(Const.DEPT_CACHE, "findById_"+deptId);
        if (baseDept == null) {
        	baseDept = baseDeptDao.findById(deptId);
            if (baseDept != null) {
                CacheKit.put(Const.DEPT_CACHE, "findById_"+deptId, baseDept);
            }
        }
        // join 真正开始的地方，前面是准备工作
		if (baseDept != null) {
			for (String attr : joinAttrs) {
				model.put(attr, baseDept.get(attr));
			}
		} else {
			throw new RuntimeException("未找到 baseDept ，baseDept 的 id 值为：" + deptId + " 可能是数据库数据不一致");
		}
	}

	/**
	 * 创建登录日志
	 */
	private void createLoginLog(String logName ,Long userId,String className,String method,String succed,String message, String loginIp) {
		Record loginLog = new Record().set("logName",logName)
									  .set("userId", userId)
									  .set("className", className)
									  .set("operator", method)
									  .set("createTime", new Date())
									  .set("succeed", succed)
									  .set("message", message)
									  .set("ip", loginIp);
		DbService.save("base_login_log", loginLog);
	}

}
